

import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:tx_live_plugin/tx_constant.dart';

///播放直播推流视频的控件
class TxLivePlay extends StatelessWidget {

  final PlayCallback? callback;
  final PlayController? controller;

  const TxLivePlay({Key? key, this.callback, this.controller}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        return AndroidView(
          viewType: platformFactory,
          creationParams: const {ViewType.key:ViewType.play},
          creationParamsCodec: const StandardMessageCodec(),
          onPlatformViewCreated: onPlatformViewCreated,
        );

      case TargetPlatform.iOS:
        return UiKitView(
          viewType: platformFactory,
          creationParams: const {ViewType.key:ViewType.play},
          creationParamsCodec: const StandardMessageCodec(),
          onPlatformViewCreated: onPlatformViewCreated,
        );

      default:
        return Center(
          child:
          Text("current platform ${Platform.operatingSystem} is not support"),
        );
    }
  }

  void onPlatformViewCreated(int id) {
    MethodChannel _channel = MethodChannel("${Channel.playChannel}$id")
      ..setMethodCallHandler(_handler);
    controller?._setChannel = _channel;
  }

  ///处理原生发过来的消息
  Future _handler(MethodCall call) async {
    var method = call.method;
    var arg = call.arguments;
    //print("---------tx live play,method $method, argument $arg");
    switch(method){
      case PlayMethod.error:
        if (arg is! String) {
          _error(PlayMethod.error,data: arg);
          return;
        }
        callback?.error(arg);
        break;
      case PlayMethod.toast:
        if (arg is! String) {
          _error(PlayMethod.toast,data: arg);
          return;
        }
        callback?.toast(arg);
        break;
      case PlayMethod.backStartPlay:
        if(arg is! bool){
          _error(PlayMethod.backStartPlay,data: arg);
          return;
        }
        callback?.backStartPlay(arg);
        break;
      case PlayMethod.startLoading:
        if(arg is! bool){
          _error(PlayMethod.startLoading,data: arg);
          return;
        }
        callback?.startLoading(arg);
        break;
      case PlayMethod.playProcess:
        if(arg is! Map){
          _error(PlayMethod.playProcess,data: arg);
          return;
        }
        callback?.playProcess(
            progress: arg[PlayKey.progress],
            duration: arg[PlayKey.duration],
            playable: arg[PlayKey.playable],
            startTime: arg[PlayKey.startTime],
            durationTime: arg[PlayKey.durationTime]);
        break;
      case PlayMethod.playStatus:
        if(arg is! int){
          _error(PlayMethod.playStatus,data: arg);
          return;
        }
        callback?.playStatus(arg);
        break;
      case PlayMethod.checkPlayForNotWifi:
        var res = await callback?.checkPlayForNotWifi();
        if(res == true || res == null){
          controller?._startPlayForNotWifi();
        }
        break;
      default:break;
    }
  }

  _error(String name, {dynamic data}) {
    print("methodName $name is error, arguments $data");
  }
}
///原生通知 flutter进行处理
abstract class PlayCallback {

  error(String? msg){}
  toast(String? msg){}
  ///播放时，遇到网络状态为不是wifi，如果用户确认要播放，true则直接播放
  Future<bool> checkPlayForNotWifi()async{
    return true;
  }
  ///视频开始播放，false表示播放失败，true表示成功开始播放
  backStartPlay(bool start){}
  ///播放视频时，显示或隐藏加载中
  startLoading(bool showLoading){}
  ///当前播放进度（毫秒）、总播放时长（毫秒）、可播放进度（毫秒）、当前播放时长（00:00:00）、播放总时长（00:00:00）
  playProcess({int? progress,int? duration,int? playable,String? startTime,String? durationTime}){}
  ///播放状态：0未播放状态，1播放中，2播放暂停
  playStatus(int? status){}

}

///播放控制
class PlayController extends ChangeNotifier {
  MethodChannel? _channel;

  set _setChannel(MethodChannel channel) => _channel = channel;

  ///通过channel通知原生处理数据
  _notifyChannel(String methodName, {dynamic data}) async {
    final c = _channel;
    if (c == null) {
      print("tx_live_plugin PlayController' channel is null，cannot use methodName $methodName");
      return -1;
    }
    return await c.invokeMethod(methodName, data);
  }

  ///无wifi情况下播放 直播视频
  _startPlayForNotWifi(){
    return _notifyChannel(PlayMethod.firstPlayRtmp);
  }

  ///未播放则播放，已播放的则暂停播放
  switchPlay(List<String> urls, {String? cacheFilePath}) {
    return _notifyChannel(PlayMethod.startPlay, data: {
      PlayKey.urls: urls,
      if (cacheFilePath != null) PlayKey.cacheFilePath: cacheFilePath,
    });
  }

  ///停止播放视频
  stopPlay(){
    return _notifyChannel(PlayMethod.stopPlay);
  }

  ///暂停播放视频
  onPause(){
    return _notifyChannel(PlayMethod.onPause);
  }

  ///重新播放视频
  onResume(){
    return _notifyChannel(PlayMethod.onResume);
  }

  ///释放
  onDestroy(){
    return _notifyChannel(PlayMethod.onDestroy);
  }

  ///是否播放中
  isPlaying(){
    return _notifyChannel(PlayMethod.isPlaying);
  }

  ///更改播放进度 Android单位秒
  seek(int progress){
    return _notifyChannel(PlayMethod.seek,data: {
      "progress" : progress,
    });
  }

  @override
  void dispose() {
    super.dispose();
    onDestroy();
  }
}